/**	@file Mul.h
 * 	@brief Representation of multiplication. */
#ifndef Mul_majdo_
#define Mul_majdo_
#include <vector>
#include "Ex.h"
namespace sympycpp {
class Number;
/**	@class Mul
 *      @brief Representation of multiplication.
 *      Mul represents multiplication of several (two or more) expressions. It's possible because multiplication
 *      is commutative binary operation*/
class Mul : public Ex {
private:
	///	@brief Here are stored all multiplicands.
	basic_container args_;
	/**	@brief Centralisation of sign management. 
	 * 	The signs of all multiplicands are adjusted to plus and the sign of multiplication mirrors adequate sign.*/
	void oper_sort();
	/**	@brief Special constructor that omits one of multiplicands. 
	 * 	This constructor is special copy constructor that omits one multiplicands.
	 * 	Usage is very dangerous, because the constructor does not check the number of operands.
	 * 	Consequently, the constructor can create an invalid object taht have only one multiplicand. 
	 * 	@warning Source multiplication has to keep three or more multiplicands.*/
	Mul(const Mul &, const_iterator);
	/**	@brief Stealing constructor.
         *      The constructors exploits memory from the input parameters.   
	 *      The first parameter have to be less than the second one by comparative function ComparerIx::mullt       
	 *      @see ComparerIx::mullt comparative function for expressions which are multiplicands 
	 *	@warning Constructor doesn't check sorting of multiplicands. 
	 *	@warning Constructor assumes that multiplicands are sorted by ComparerIx::mullt(). */
	Mul(Ex * & v, Ex * & x, const allocationPolicy flag);
        /**	@brief 	Stealing constructor.
         *      Constructor exploits memory from all elements from v. 
	 *      @see allocationPolicy : special memory management
	 *      @see containerSort : sorting function for expressions
	 *	@warning the container have to be sorted by containerSort by comparative function for multiplication.	*/
	Mul(basic_container & v, const allocationPolicy flag);
public:
	///	@brief Standard copy constructor.
	Mul(const Mul &);
	virtual ~Mul();
	/**	@brief Omiting of multiplicand at particular position.
	 *	The input iterator after omiting points to the next element (or end() if last element has been omited). 
	 * 	@warning If the number of multiplicands is two then omiting  will be aborted.
	 * 	@warning Omited multiplicand will be also deleted (memory will be released). 
	 * 	@retval true == omitting is successfull
	 * 	@retval false == omitting is aborted (there are only two multiplicands probably)*/ 
	bool omit(iterator &  index);
	virtual std::string treeView(const int i) const;
	virtual size_t rsize(const bool all = true) const;
	virtual size_t asize() const;
	virtual size_t size() const;
	virtual std::string str() const;
	/**	@brief Special consversion into the std::string.
	 * 	Auxiliary function for unsigned_str(). */ 
	virtual std::string mulStr(const std::string &) const;
        virtual std::string unsigned_str() const;
        virtual Ex * diff(const Sym &) const;
	virtual Ex * copy() const; 
	virtual Number Multiplicity() const; 
	virtual bool isMultiple() const;
	friend class Utilities;
	friend class Substitution;
	friend class ComparerIx;
	friend class Operations;
};
}
#endif
